package forum.client.ui;


import forum.client.MainView;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import forum.client.controllerlayer.*;
import forum.client.ui.events.ForumTreeErrorEvent;
import java.util.Vector;
import javax.swing.*;

/**
 *
 * @author furmanal
 */
public class Search extends javax.swing.JFrame implements SearchHandler  {

	private static final long serialVersionUID = 7013762130399245241L;
	private ExecutorService m_pool = Executors.newCachedThreadPool();
        private ControllerHandler m_pipe;
	Component fatherComp;
        String searchResults;
        String searchFor;
        int resultsCount;
        int rangeStart;
        int rangeEnd;
        String searchBy;
        ForumTree tree;
        Component myself;

    /** Creates new form Search */
    public Search() {
    	this.m_pipe = ControllerHandlerFactory.getPipe();
    	this.m_pipe.addObserver(new SearchObserver(this));
        initComponents();
        this.setTitle("BannanaForum- Search");
        this.setLocationRelativeTo(null);
        this.setResizable(false);
        this.rangeStart = 0;
        this.rangeEnd = 10;
        
        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                closeButtonActionPerformed(null);
            }
        });
    }

    public Search(Component c, String search, String byWhat, ForumTree t) {
        this();
        this.fatherComp = c;
        this.searchFor = search;
        this.searchBy = byWhat;
        this.tree = t;
        this.openPost.setEnabled(false);
        this.myself = this;
        
            SwingWorker<String[], Void> searchWorker = new SwingWorker<String[], Void>() {
            String[] results;
            public String[] doInBackground() {
                String str = searchTextField.getText();
                if (searchBy.equals("author"))
                        results = m_pipe.searchByAuthor(searchFor, 0, 1000, myself);
                else
                        results = m_pipe.searchByContent(searchFor, 0, 1000, myself);

                return results;
            }
        };
        m_pool.execute(searchWorker);
        try{
            String[] searchRes = (String[])searchWorker.get();
            if(searchRes[0].equals("succ")){
                searchResults = searchRes[1];
                String[] sRes = searchResults.split("\n");
                Vector<String> resultsVec = new Vector<String>();
                if(!sRes[0].equals("")){
                    this.resultsCount = Integer.parseInt(sRes[0]);
                }
                performSearch();
            }
            else{
                m_pipe.notifyObservers(new ForumTreeErrorEvent(searchRes[1]));
            }
        }
        catch (InterruptedException ignore) {}
        catch (java.util.concurrent.ExecutionException e) {
             JOptionPane.showMessageDialog(this,
			    "search swing worker failed",
			    "Operation failed.",
			    JOptionPane.WARNING_MESSAGE);
        }
        
        //displayResults(res, rangeStart, rangeEnd);
    }

	@Override
	public void displayResults(String res, int start, int end) {
            //JTextArea txt = new JTextArea(encodedView);
            //txt.setEditable(false);
            //jScrollPane1.setViewportView(txt);
                //this.resultsList.setListData(searchResults.split("\n"));
            this.searchResults = res;
            String[] sRes = res.split("\n");
            Vector<String> resultsVec = new Vector<String>();
            //this.resultsCount = Integer.parseInt(sRes[0]);

            for(int i=1; i<sRes.length; i++){
                resultsVec.add(sRes[i]);
            }
            if (resultsCount <= end){
                DisplayingResults.setText("Displaying results from "+start +" to "+ resultsCount +" out of "+ resultsCount+" results");
            } else{
                DisplayingResults.setText("Displaying results from "+start +" to "+ end +" out of "+ resultsCount+" results");
            }
            if (start == 0){
                prevButton.setEnabled(false);
            }else{
                prevButton.setEnabled(true);
            }
            if (resultsCount <= end){
                 nextButton.setEnabled(false);
            }else{
                 nextButton.setEnabled(true);
            }
            this.resultsList.setListData(resultsVec);

	}

	@Override
	public void notifyError(String errorMessage) {
		JOptionPane.showMessageDialog(this,
			    errorMessage,
			    "Operation failed.",
			    JOptionPane.WARNING_MESSAGE);
	}

        public void performSearch(){
            SwingWorker<String[], Void> searchWorker = new SwingWorker<String[], Void>() {
            String[] results;
            public String[] doInBackground() {
                String str = searchTextField.getText();
                if (searchBy.equals("author"))
                        results = m_pipe.searchByAuthor(searchFor, rangeStart, rangeEnd, searchButton);
                else
                        results = m_pipe.searchByContent(searchFor, rangeStart, rangeEnd, searchButton);

                return results;
            }
        };
        m_pool.execute(searchWorker);
        try{
            String[] searchRes = (String[])searchWorker.get();
            if(searchRes[0].equals("succ")){
                searchResults = searchRes[1];
                displayResults(searchResults, rangeStart, rangeEnd);
            }
            else{
                m_pipe.notifyObservers(new ForumTreeErrorEvent(searchRes[1]));
            }
        }
        catch (InterruptedException ignore) {}
        catch (java.util.concurrent.ExecutionException e) {
             JOptionPane.showMessageDialog(this,
			    "search swing worker failed",
			    "Operation failed.",
			    JOptionPane.WARNING_MESSAGE);
        }
        
        }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        buttonGroup1 = new javax.swing.ButtonGroup();
        searchTextField = new javax.swing.JTextField();
        searchButton = new javax.swing.JButton();
        nextButton = new javax.swing.JButton();
        prevButton = new javax.swing.JButton();
        DisplayingResults = new javax.swing.JLabel();
        closeButton = new javax.swing.JButton();
        authorRadioButton = new javax.swing.JRadioButton();
        contentRadioButton = new javax.swing.JRadioButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        resultsList = new javax.swing.JList();
        openPost = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        searchTextField.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchTextFieldActionPerformed(evt);
            }
        });

        searchButton.setIcon(new javax.swing.ImageIcon(".\\images\\search2.jpg")); // NOI18N
        searchButton.setText("Search");
        searchButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchButtonActionPerformed(evt);
            }
        });

        nextButton.setIcon(new javax.swing.ImageIcon(".\\images\\go-next.png")); // NOI18N
        nextButton.setText("Next");
        nextButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                nextButtonActionPerformed(evt);
            }
        });

        prevButton.setIcon(new javax.swing.ImageIcon(".\\images\\go-previous.png")); // NOI18N
        prevButton.setText("Prev");
        prevButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                prevButtonActionPerformed(evt);
            }
        });

        DisplayingResults.setText("Displaying 0 of 0 results");

        closeButton.setIcon(new javax.swing.ImageIcon(".\\images\\home.jpg")); // NOI18N
        closeButton.setText("Back to Forum");
        closeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeButtonActionPerformed(evt);
            }
        });

        buttonGroup1.add(authorRadioButton);
        authorRadioButton.setSelected(true);
        authorRadioButton.setText("By Author");
        authorRadioButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                authorRadioButtonActionPerformed(evt);
            }
        });

        buttonGroup1.add(contentRadioButton);
        contentRadioButton.setText("By Content");

        resultsList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                resultsListValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(resultsList);

        openPost.setIcon(new javax.swing.ImageIcon(".\\images\\goto.jpg")); // NOI18N
        openPost.setText("Open selected post");
        openPost.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openPostActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(241, 241, 241)
                .addComponent(DisplayingResults)
                .addContainerGap(321, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(42, 42, 42)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(searchTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE)
                        .addGap(18, 18, 18)
                        .addComponent(authorRadioButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(contentRadioButton)
                        .addGap(18, 18, 18)
                        .addComponent(searchButton)
                        .addGap(44, 44, 44))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 394, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(openPost)
                        .addContainerGap())))
            .addGroup(layout.createSequentialGroup()
                .addGap(131, 131, 131)
                .addComponent(prevButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(nextButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(closeButton)
                .addContainerGap(254, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(51, 51, 51)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(searchButton)
                    .addComponent(authorRadioButton)
                    .addComponent(contentRadioButton))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(17, 17, 17)
                        .addComponent(DisplayingResults)
                        .addGap(14, 14, 14)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 237, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(prevButton)
                            .addComponent(nextButton)
                            .addComponent(closeButton)))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(150, 150, 150)
                        .addComponent(openPost)))
                .addContainerGap(27, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void prevButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevButtonActionPerformed
        this.rangeStart -= 10;
        this.rangeEnd -= 10;
        performSearch();
}//GEN-LAST:event_prevButtonActionPerformed

    private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
        m_pipe.refreshForum(m_pool);
        this.setVisible(false);
        ((MainView)fatherComp).getBackToForum().setVisible(false);
        ((MainView)fatherComp).getBackToSearch().setVisible(false);
        this.fatherComp.setVisible(true);
    }//GEN-LAST:event_closeButtonActionPerformed

    private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
        this.rangeEnd = 100;
        this.rangeStart = 0;
        if (searchTextField.getText().length()==0) {
            JOptionPane.showMessageDialog(this,
			    "Please enter a search key before hitting \"search\".",
			    "Operation failed.",
			    JOptionPane.WARNING_MESSAGE);
            return;
        }
        this.searchFor = searchTextField.getText();
        if (authorRadioButton.isSelected()){
            this.searchBy = "author";
        }else{
            this.searchBy = "content";
        }
        performSearch();
    }//GEN-LAST:event_searchButtonActionPerformed

    private void searchTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchTextFieldActionPerformed
        // TODO add your handling code here:
}//GEN-LAST:event_searchTextFieldActionPerformed

    private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextButtonActionPerformed
        this.rangeStart += 10;
        this.rangeEnd += 10;
        performSearch();
    }//GEN-LAST:event_nextButtonActionPerformed

    private void authorRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_authorRadioButtonActionPerformed

    }//GEN-LAST:event_authorRadioButtonActionPerformed

    private void openPostActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openPostActionPerformed
        String selected = (String)resultsList.getSelectedValue();
        String[] parsedSelected = selected.split(" ");
        int postID = Integer.parseInt(parsedSelected[0]);
        String[] forumView = m_pipe.getOneSearchView(postID);
        if(forumView[0].equals("succ")){
            tree.refreshForum(forumView[1]);
            this.setVisible(false);
            fatherComp.setVisible(true);
            ((MainView)fatherComp).getBackToForum().setVisible(true);
            ((MainView)fatherComp).getBackToSearch().setVisible(true);
        }
        else{
            m_pipe.notifyObservers(new ForumTreeErrorEvent(forumView[1]));
        }
    }//GEN-LAST:event_openPostActionPerformed

    private void resultsListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_resultsListValueChanged
        this.openPost.setEnabled(true);
    }//GEN-LAST:event_resultsListValueChanged


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel DisplayingResults;
    private javax.swing.JRadioButton authorRadioButton;
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JButton closeButton;
    private javax.swing.JRadioButton contentRadioButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton nextButton;
    private javax.swing.JButton openPost;
    private javax.swing.JButton prevButton;
    private javax.swing.JList resultsList;
    private javax.swing.JButton searchButton;
    private javax.swing.JTextField searchTextField;
    // End of variables declaration//GEN-END:variables

}
